#pragma once

#include <iostream>
#include <vector>
#include <cassert>
#include <string>

namespace Log
{
#define BUFFER_DEFAULT_SIZE (1 * 1024 * 1024)
#define BUFFER_THRESHOLD_SIZE (10 * 1024 * 1024)
#define BUFFER_INCREMENT_SIZE (1 * 1024 * 1024)
    class Buffer
    {
    public:
        Buffer() : _buffer(BUFFER_DEFAULT_SIZE), _writer_idx(0), _reader_idx(0) {}
        bool empty() { return _reader_idx == _writer_idx; }
        size_t readAbleSize() { return _writer_idx - _reader_idx; }
        size_t writeAbleSize() { return _buffer.size() - _writer_idx; }
        // 初始化缓冲区
        void reset() { _reader_idx = _writer_idx = 0; }

        void swap(Buffer &buf)
        {
            _buffer.swap(buf._buffer);
            std::swap(_writer_idx, buf._writer_idx);
            std::swap(_reader_idx, buf._reader_idx);
        }

        void push(const char *data, size_t len)
        {
            // 1 如果空间不够则进行扩容操作
            ensureEnoughSpace(len);
            std::copy(data, data + len, &_buffer[_writer_idx]);
            _writer_idx += len;
        }

        const char *begin() { return &_buffer[_reader_idx]; }

        void pop(size_t len)
        {
            assert(len <= readAbleSize());
            _reader_idx += len;
        }

    protected:
        void ensureEnoughSpace(size_t len)
        {
            if (len <= writeAbleSize())
                return;

            size_t new_capacity = 0;
            if (_buffer.size() <= BUFFER_THRESHOLD_SIZE)
                new_capacity = _buffer.size() * 2 + len; /*这里需要加上len 因为 可能*2 之后扩容空间可能仍然不足*/
            else
                new_capacity = _buffer.size() + BUFFER_INCREMENT_SIZE + len;

            _buffer.resize(new_capacity);
        }

    private:
        std::vector<char> _buffer; // 存放格式化后字符串的缓冲区
        size_t _writer_idx;        // buffer中可写位置索引
        size_t _reader_idx;        // buffer中读写位置索引
    };
}